﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; // Messagebox
using System.Net; // Pour httpWebRequest
using System.IO; // Stream, Directory, Path
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Reflection; // pour Process
using SeriesUpdatesCommon;

namespace SeriesUpdates
{
    class CadreSerie
    {
        private DB _db;
        private MainWindow _parentWindow;
        private string name;
        private string url;
        private string saison;
        private int lastEpisodeNumber;
        private string urlFile;
        private List<Episode> lastEpisodes;
        private Panel _mainPanel;
        private Panel _mainNoMajPanel;
        Button[] btnNewSaison;
        int iSaison;

        private StreamPlanetSeries _streamSerie;


        public CadreSerie(MainWindow parentWindow, string name, string url, string saison, int lastEpisodeNumber)
        {
            this._db = DB.GetDB();
            this._parentWindow = parentWindow;
            this._mainPanel = parentWindow.getPanel();
            this._mainNoMajPanel = parentWindow.getPanelNoMaj();
            this.name = name;
            this.url = url;
            this.saison = saison;
            this.lastEpisodeNumber = lastEpisodeNumber;
            this.urlFile = "";


            this._streamSerie = new StreamPlanetSeries();


            btnNewSaison = new Button[this._db.GetNbSeries()];
            iSaison = 0;
        }

        /**
         * Fonction qui permet de créer le panel avec toutes les informations qu'il doit y avoir dedans
         **/
        public void createPanel()
        {
            // On récupère le code source de la page
            this._streamSerie.fetchSourceData(this.url);

            ToolTip panelTooltip = new ToolTip();
            ToolTip btnDlTooltip = new ToolTip();

            Panel newPanel = new Panel();
            newPanel.Width = 224;
            newPanel.Height = 176;
            newPanel.BorderStyle = BorderStyle.Fixed3D;
            newPanel.BackColor = Color.Lavender;

            // On télécharge l'image de la série
            this.urlFile = this.getPicture();

            Panel panelPicture = new Panel();
            panelPicture.Width = 224;
            panelPicture.Height = 93;
            panelPicture.Dock = DockStyle.Top;
            panelPicture.Location = new Point(0, 0);
            if (!string.IsNullOrEmpty(this.urlFile))
            {
                panelPicture.BackgroundImage = Image.FromFile(this.urlFile);
            }
            else
            {
                panelPicture.BackgroundImage = Properties.Resources._404;
            }
            panelPicture.BackgroundImageLayout = ImageLayout.Stretch;

            panelTooltip.SetToolTip(panelPicture, this.name);
            newPanel.Controls.Add(panelPicture);

            Panel panelEpi = new Panel();
            panelEpi.Width = 224;
            panelEpi.Height = 61;
            panelEpi.Dock = DockStyle.Bottom;
            panelEpi.Location = new Point(0, 115);
            panelEpi.BackColor = Color.White;
            panelEpi.AutoScroll = true;

            Label lbl_Saison = new Label();
            lbl_Saison.Parent = newPanel;
            lbl_Saison.AutoSize = false;
            lbl_Saison.Width = 100;
            int X = (newPanel.Width / 2) - (lbl_Saison.Width / 2);
            lbl_Saison.Location = new Point(X, 96);
            lbl_Saison.Text = saison;
            lbl_Saison.AutoSize = true;

            // On récupère le dernier épisode depuis le site internet
            this.lastEpisodes = this.lastEpisodesFromWebsite();

            Panel imageNew;
            Label[] lblSerieName = new Label[this.lastEpisodes.Count];
            Button[] btnSerieDL = new Button[this.lastEpisodes.Count];

            int i = 0;

            foreach (Episode episode in this.lastEpisodes)
            {
                imageNew = new Panel();
                imageNew.Width = 24;
                imageNew.Height = 24;
                imageNew.BackgroundImage = Properties.Resources.newEpisode;
                imageNew.BackgroundImageLayout = ImageLayout.Stretch;
                imageNew.Location = new Point(5, 3 + i * 22);

                lblSerieName[i] = new Label();
                lblSerieName[i].Parent = newPanel;
                lblSerieName[i].AutoSize = true;
                lblSerieName[i].Location = new Point(35, 8 + i * 22);
                lblSerieName[i].Text = episode.name;

                btnSerieDL[i] = new Button();
                btnSerieDL[i].Parent = newPanel;
                btnSerieDL[i].Width = 16;
                btnSerieDL[i].Height = 16;
                btnSerieDL[i].Location = new Point(170, 6 + i * 22);
                btnSerieDL[i].Tag = episode.url + "|" + this.name + "|" + episode.numero;
                btnSerieDL[i].Click += goDownloadUrl_Click;
                btnSerieDL[i].Image = new Bitmap(Properties.Resources.dlEpisode, 16, 16);
                btnSerieDL[i].FlatStyle = FlatStyle.Flat;
                btnSerieDL[i].FlatAppearance.BorderSize = 0;
                btnSerieDL[i].FlatAppearance.MouseDownBackColor = Color.Transparent;
                btnSerieDL[i].FlatAppearance.MouseOverBackColor = Color.Transparent;
                btnSerieDL[i].BackColor = Color.Transparent;

                btnDlTooltip.SetToolTip(btnSerieDL[i], "Télécharger");

                panelEpi.Controls.Add(imageNew);
                panelEpi.Controls.Add(lblSerieName[i]);
                panelEpi.Controls.Add(btnSerieDL[i]);

                i++;
            }

            // On vérifie si il y a une nouvelle saison
            string newSaison = this.searchNextSaison();

            // Pas de nouvel épisode
            if (panelEpi.Controls.Count == 0)
            {
                panelPicture.MouseEnter += panelPicture_MouseEnter;
                panelEpi.MouseEnter += panelEpi_MouseEnter;

                // Nouvelle saison disponible
                if (newSaison != "")
                {
                    ToolTip pnlNewSaisonTooltip = new ToolTip();

                    btnNewSaison[iSaison] = new Button();
                    btnNewSaison[iSaison].Width = 40;
                    btnNewSaison[iSaison].Height = 40;
                    int xBtnNewSaison = (panelEpi.Width / 2) - (btnNewSaison[iSaison].Width / 2);
                    btnNewSaison[iSaison].Location = new Point(xBtnNewSaison, 9);
                    btnNewSaison[iSaison].Image = new Bitmap(Properties.Resources.newSaison, 40, 40);
                    btnNewSaison[iSaison].Tag = this.name + "|" + newSaison;
                    btnNewSaison[iSaison].MouseClick += btnNewSaison_MouseClick;
                    btnNewSaison[iSaison].FlatStyle = FlatStyle.Flat;
                    btnNewSaison[iSaison].FlatAppearance.BorderSize = 0;
                    btnNewSaison[iSaison].FlatAppearance.MouseDownBackColor = Color.Transparent;
                    btnNewSaison[iSaison].FlatAppearance.MouseOverBackColor = Color.Transparent;
                    btnNewSaison[iSaison].BackColor = Color.Transparent;

                    pnlNewSaisonTooltip.SetToolTip(btnNewSaison[iSaison], "Nouvelle saison disponible !");

                    panelEpi.Controls.Add(btnNewSaison[iSaison]);

                    iSaison++;
                    newPanel.Controls.Add(panelPicture);
                    newPanel.Controls.Add(panelEpi);  
                    this.addPanel(newPanel);
                }
                else
                {
                    // La série est terminée
                    if(this._streamSerie.isEndedSerie())
                    {
                        ToolTip pbFinishedTooltip = new ToolTip();

                        PictureBox pbFinished = new PictureBox();
                        pbFinished.Width = 35;
                        pbFinished.Height = 36;
                        int xPbFinished = (panelEpi.Width / 2) - (pbFinished.Width / 2);
                        pbFinished.Location = new Point(xPbFinished, 13);
                        pbFinished.Image = new Bitmap(Properties.Resources.finishedSeries, 35, 36);
                        pbFinished.BackColor = Color.Transparent;

                        pbFinishedTooltip.SetToolTip(pbFinished, "Série terminée !");

                        panelEpi.Controls.Add(pbFinished);
                        newPanel.Controls.Add(panelPicture);
                        newPanel.Controls.Add(panelEpi);
                        this.addEmptyPanel(newPanel);
                    }
                    else
                    {
                        panelEpi.BackColor = Color.Gainsboro;

                        newPanel.Controls.Add(panelPicture);
                        newPanel.Controls.Add(panelEpi);
                        this.addEmptyPanel(newPanel);
                    }
                }
            }
            else
            {
                newPanel.Controls.Add(panelEpi);

                this.addPanel(newPanel);
            }
        }

        void btnNewSaison_MouseClick(object sender, MouseEventArgs e)
        {
            ((Button)sender).FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);

            string tagButton = ((Button)sender).Tag.ToString();
            string[] tagSearch = tagButton.Split(new string[] { "|" }, StringSplitOptions.None);

            this._db.UpdateSeries(tagSearch[0], "", tagSearch[1], Constants.serieUpdateType.saison);

            // On refresh toutes les séries sur la fenêtre principale
            this._parentWindow.refreshAndShowAll();
        }

        private void callInvoke(Panel mainContainer, Panel newPanel)
        {
            mainContainer.Invoke((MethodInvoker)(() =>
            {
                mainContainer.Controls.Add(newPanel);
            }));
        }

        private void addPanel(Panel panel)
        {
            panel.Margin = new Padding(10, 0, 10, 20);

            this.callInvoke(this._mainPanel, panel);
        }

        private void addEmptyPanel(Panel panel)
        {
            this.callInvoke(this._mainNoMajPanel, panel);
        }

        void panelPicture_MouseEnter(object sender, EventArgs e)
        {
            this._mainNoMajPanel.Focus();
        }

        void panelEpi_MouseEnter(object sender, EventArgs e)
        {
            this._mainNoMajPanel.Focus();
        }

        private void goDownloadUrl_Click(object sender, EventArgs e)
        {
            ((Button)sender).FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);

            string tagButton = ((Button)sender).Tag.ToString();
            string[] tagSearch = tagButton.Split(new string[] { "|" }, StringSplitOptions.None);

            this._db.UpdateSeries(tagSearch[1], tagSearch[2], "");
            Process.Start(tagSearch[0]);
        }

        /**
         * Fonction qui permet de récupérer les derniers épisodes
         **/
        private List<Episode> lastEpisodesFromWebsite()
        {
            List<Episode> newEpisodes = new List<Episode>();

            try
            {
                newEpisodes = this._streamSerie.getEpisodes(this.saison, this.lastEpisodeNumber);
            }
            catch (Exception exception)
            {
                MessageBox.Show(@"Un problème a été rencontré pour récupérer les données de la série '" + this.name + "' : " + exception);
            }

            return newEpisodes;
        }

        private string searchNextSaison()
        {
            string resultSaison = "";

            try
            {
                resultSaison = this._streamSerie.getNextSaison(this.saison);
            }
            catch(Exception e)
            {
                MessageBox.Show(@"Un problème a été rencontré pour récupérer les données de la série '" + this.name + "' : " + e);
            }

            return resultSaison;
        }

        private string getPicture()
        {
            string rootPath = "Image";
            bool isExists = Directory.Exists(rootPath);

            if (!isExists)
            {
                Directory.CreateDirectory(rootPath);
            }               
            
            string fileName = Path.Combine(rootPath, this.name + ".png");

            if (!File.Exists(fileName))
            {
                if (!this._streamSerie.downloadPicture(fileName))
                {
                    fileName = "";
                }
            }

            return fileName;
        }
    }
}
